from database.settings import settings
from database.database import DBSessionManager
from models import TaskErrorRequest
from typing import List, Dict, Any, Optional


class TaskErrorRequestDao:
    def __init__(self):
        # 获取全局配置的会话管理器配置
        self.session_config = settings.get_db_session_config(
            # 可以针对TaskErrorRequestDao进行特殊配置
            exclude_fields=set()  # 如有需要可排除敏感字段
        )

    def add_request(self, task: TaskErrorRequest) -> Dict[str, Any]:
        """
        添加错误请求记录

        Args:
            task: 错误请求对象

        Returns:
            创建的序列化错误请求对象
        """
        with DBSessionManager(**self.session_config) as db:
            db.add(task)
            db.commit()
            # 返回序列化结果（自动序列化）
            return db.get_by_id(TaskErrorRequest, task.id)

    def get_all_task_error_requests(self) -> List[Dict[str, Any]]:
        """
        获取所有错误请求记录（自动序列化）

        Returns:
            序列化后的错误请求列表
        """
        with DBSessionManager(**self.session_config) as db:
            return db.all(db.query(TaskErrorRequest))

    def get_error_requests_by_type(self, request_type: str) -> List[Dict[str, Any]]:
        """
        按类型获取错误请求

        Args:
            request_type: 请求类型

        Returns:
            序列化后的错误请求列表
        """
        with DBSessionManager(**self.session_config) as db:
            return db.all(
                db.query(TaskErrorRequest)
                .filter(TaskErrorRequest.type == request_type)
                .order_by(TaskErrorRequest.create_time.desc())
            )

    def get_error_requests_by_site_id(self, site_id: int) -> List[Dict[str, Any]]:
        """
        按站点ID获取错误请求

        Args:
            site_id: 站点ID

        Returns:
            序列化后的错误请求列表
        """
        with DBSessionManager(**self.session_config) as db:
            return db.all(
                db.query(TaskErrorRequest)
                .filter(TaskErrorRequest.site_id == site_id)
                .order_by(TaskErrorRequest.create_time.desc())
            )

    def delete_task_error_request_by_id(self, request_id: int) -> bool:
        """
        删除错误请求记录

        Args:
            request_id: 请求ID

        Returns:
            是否删除成功
        """
        with DBSessionManager(**self.session_config) as db:
            # 使用更高效的方式删除，禁用会话同步
            result = db.query(TaskErrorRequest).filter(TaskErrorRequest.id == request_id).delete(
                synchronize_session=False
            )
            db.commit()
            return result > 0

    def batch_delete_error_requests(self, request_ids: List[int]) -> int:
        """
        批量删除错误请求

        Args:
            request_ids: 请求ID列表

        Returns:
            删除的记录数
        """
        with DBSessionManager(**self.session_config) as db:
            result = db.query(TaskErrorRequest).filter(TaskErrorRequest.id.in_(request_ids)).delete(
                synchronize_session=False
            )
            db.commit()
            return result

    def delete_old_error_requests(self, days: int = 30) -> int:
        """
        删除指定天数前的错误请求

        Args:
            days: 保留天数

        Returns:
            删除的记录数
        """
        from datetime import datetime, timedelta
        cutoff_date = datetime.now() - timedelta(days=days)

        with DBSessionManager(**self.session_config) as db:
            result = db.query(TaskErrorRequest).filter(TaskErrorRequest.create_time < cutoff_date).delete(
                synchronize_session=False
            )
            db.commit()
            return result

    def process_error_requests_in_batches(self, process_func, filter_condition=None) -> int:
        """
        流式处理错误请求（避免内存问题）

        Args:
            process_func: 处理函数
            filter_condition: 过滤条件（可选）

        Returns:
            处理的记录数
        """
        with DBSessionManager(**self.session_config) as db:
            query = db.query(TaskErrorRequest)
            if filter_condition:
                query = query.filter(filter_condition)

            return db.process_in_batches(
                query,
                process_func,
                serialize=True
            )